package guarded.suspension;

import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.Callable;

/**
 * Created by Administrator on 2017/3/16.
 */
public class AlarmAgent {

    private volatile boolean connectedToServer = false;


    private final Predicate agentConnected = new Predicate() {
        @Override
        public boolean evaluate() {
            return connectedToServer;
        }
    };


    private final Blocker blocker=new ConditionVarBlocker();


    private final Timer heartbeatTimer=new Timer(true);


    public void sendAlarm(final AlarmInfo alarm) throws Exception{

        GuardedAction<Void> guardedAction = new GuardedAction<Void>(agentConnected) {
            @Override
            public Void call() throws Exception {
                doSendAlarm(alarm);
                return null;
            }
        };

        blocker.callWithGuard(guardedAction);
    }

    private void doSendAlarm(AlarmInfo alarm) {

        System.out.println("send alarm "+alarm);


        try{
            Thread.sleep(500);
        }catch (Exception e){

        }
    }

    public void init () {

        Thread connectingThread = new Thread(new ConnectingTask());

        connectingThread.start();

        heartbeatTimer.schedule(new HeartbeatTask(),60000,2000);

    }

    public void disconnect() {

        connectedToServer = false;
    }


    protected void onConnected(){
        try {
            blocker.signalAfter(new Callable<Boolean>() {
                @Override
                public Boolean call() throws Exception {
                    connectedToServer=true;
                    System.out.println("connected to server...");
                    return Boolean.TRUE;
                }
            });
        }catch (Exception e){

        }
    }

    protected void onDisconnected(){
        connectedToServer = false;
    }

    private class ConnectingTask implements Runnable {

        @Override
        public void run() {
            try{
                Thread.sleep(500);
            }catch (Exception e){

            }
            onConnected();
        }
    }


    private class HeartbeatTask extends TimerTask {
        @Override
        public void run() {
            if(!testConnection()){
                onDisconnected();
                reconnect();
            }
        }

        private void reconnect() {
            ConnectingTask connectingTask=new ConnectingTask();
            connectingTask.run();
        }

        private boolean testConnection() {
            return true;
        }
    }

    public static void main(String[] args) {
        AlarmAgent aa=new AlarmAgent();
        aa.init();
    }
}
